package mirrormonkey.commons.syncset;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import mirrormonkey.core.server.ServerCoreModule;
import mirrormonkey.framework.ConnectionInfo;
import mirrormonkey.framework.entity.SyncEntity;

import com.jme3.network.MessageConnection;

public class SyncEntitySet {

	private final Map<Integer, EntityRegistration> data;

	private final Set<ConnectionInfo> connections;

	private final ServerCoreModule module;

	public SyncEntitySet(ServerCoreModule module) {
		this.data = new LinkedHashMap<Integer, EntityRegistration>();
		this.connections = new LinkedHashSet<ConnectionInfo>();
		this.module = module;
	}

	public void add(SyncEntity entity, Class<? extends SyncEntity> clientClass,
			Object... constrParams) {
		EntityRegistration r = new EntityRegistration(entity, clientClass,
				constrParams);
		for (ConnectionInfo i : connections) {
			module.addMapping(i.connection, entity, clientClass, constrParams);
		}
		data.put(entity.getData().id, r);
	}

	public void remove(SyncEntity entity) {
		for (ConnectionInfo i : connections) {
			module.removeMapping(i.connection, entity);
		}
		data.remove(entity.getData().id);
	}

	public void add(MessageConnection connection) {
		for (EntityRegistration i : data.values()) {
			module.addMapping(connection, i.entity, i.clientClass,
					i.constrParams);
		}
		connections.add(module.getConnectionInfo(connection));
	}

	public void remove(MessageConnection connection) {
		for (EntityRegistration i : data.values()) {
			module.removeMapping(connection, i.entity);
		}
		connections.remove(connection);
	}

	private static final class EntityRegistration {

		public final SyncEntity entity;

		public final Class<? extends SyncEntity> clientClass;

		public final Object[] constrParams;

		public EntityRegistration(SyncEntity entity,
				Class<? extends SyncEntity> clientClass, Object[] constrParams) {
			this.entity = entity;
			this.clientClass = clientClass;
			this.constrParams = constrParams;
		}

	}

}
